package com.stockz.downloaderx;

import java.util.Date;
import java.util.List;

import com.stockz.core.model.Bar;
import com.stockz.core.model.Scrip;
import com.stockz.downloaderx.Downloader.Callback.EVENT;
import com.stockz.downloaderx.Downloader.Callback.TYPE;

public abstract class AbstractSpanDownloader extends AbstractDownloader
		implements SpanDownloader {

	public abstract String constructUri(Scrip scrip, Date start, Date end);

	public abstract String downloadRawData(String uri);

	public abstract List<Bar> parse(String text, Scrip scrip);

	@Override
	public void download(Scrip scrip, Date startDate, Date endDate,
			List<Callback> callbackList) {

		if (scrip != null && startDate != null && endDate != null
				&& (endDate.after(startDate) || endDate.equals(startDate))
				&& callbackList != null
				&& !callbackList.isEmpty()) {

			Download download = new Download();
			download.setBarList(null);
			download.setStartDate(startDate);
			download.setEndDate(endDate);
			download.setScrip(scrip);
			download.setScrip(null);
			executeCallbacks(download, EVENT.LOOP, TYPE.START, callbackList);

			try {

				String rawData = "";
				executeCallbacks(download, EVENT.DOWNLOAD, TYPE.START,callbackList);
				try {
					rawData = downloadRawData(constructUri(scrip, startDate,endDate));
					executeCallbacks(download, EVENT.DOWNLOAD, TYPE.SUCCESS,callbackList);
				} catch (Exception e) {
					executeCallbacks(download, EVENT.DOWNLOAD, TYPE.FAIL,callbackList);
				} finally {
					executeCallbacks(download, EVENT.DOWNLOAD, TYPE.END,callbackList);
				}
				
				try {
					executeCallbacks(download, EVENT.PARSE, TYPE.START,callbackList);
					List<Bar> barList = parse(rawData, scrip);
					download.setBarList(barList);
					executeCallbacks(download, EVENT.PARSE, TYPE.SUCCESS,callbackList);
				} catch (Throwable t) {
					executeCallbacks(download, EVENT.PARSE, TYPE.FAIL,callbackList);
				} finally {
					executeCallbacks(download, EVENT.PARSE, TYPE.END,callbackList);
				}
				executeCallbacks(download, EVENT.LOOP, TYPE.SUCCESS,callbackList);
			} catch (Throwable t) {
				executeCallbacks(download, EVENT.LOOP, TYPE.FAIL, callbackList);
			} finally {
				executeCallbacks(download, EVENT.LOOP, TYPE.END, callbackList);
			}
		}
	}

}
